
#include "apdu_lib_key_mgr.h"
#include "apdu_lib_common.h"

#include "../apdu.core/apdu.h"

#include "../../mk_lib/mk_auto_ptr.h"
#include "../../mk_lib/mk_utility.h"

#include <stdlib.h>
#include <string.h>
#include "../apdu.algo/mac.h"

extern int	g_sw;

int app_export_public_key( HANDLE devHandle, int app_id, int container_id, int key_type, 
						  unsigned char * pub_key_blob, int *key_blob_len )
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_export_public_key(app_id, container_id, key_type);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(*key_blob_len < data_len)
	{
		return 3;
	}
	*key_blob_len = data_len;
	memcpy(pub_key_blob, data, data_len);
	return 0;
}

int app_import_session_key( HANDLE devHandle, int app_id, int container_id, int key_spec, unsigned long alg_id,
						   unsigned char * wraped_data, unsigned long wraped_len, int * session_key_id )
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_import_session_key(app_id, container_id, key_spec, alg_id, wraped_data, wraped_len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(data_len < 2)
	{
		return 3;
	}

	* session_key_id = data[0] * 256 + data[1];
	return 0;
}

int app_destroy_session_key( HANDLE devHandle, int app_id, int container_id, int session_key_id )
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_destroy_session_key(app_id, container_id, session_key_id);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	return 0;
}

int app_gen_container_session_key( HANDLE devHandle, int app_id, int container_id, unsigned long alg_id, int * session_key_id )
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_gen_session_key(app_id, container_id, alg_id);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(data_len < 2)
	{
		return 3;
	}

	* session_key_id = data[0] * 256 + data[1];
	return 0;
}

int app_set_container_session_key( HANDLE devHandle, int app_id, int container_id, unsigned long alg_id, 
						unsigned char * key_value, int len, int * session_key_id )
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_set_session_key(app_id, container_id, alg_id, key_value, len);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(data_len < 2)
	{
		return 3;
	}

	* session_key_id = data[0] * 256 + data[1];
	return 0;
}

int app_set_session_key_from_file( HANDLE devHandle, int app_id, int container_id, unsigned long alg_id, 
								  char * file_name, int offset, int * session_key_id)
{
	apdu * newApdu  =  NULL;
	newApdu = get_key_mgr()->create_apdu_set_session_key_from_file(app_id, container_id, alg_id, offset, file_name);

	mk_auto_ptr<apdu> ap(newApdu);

	if( 0 != get_dev_mgr()->transmit_apdu(devHandle,newApdu, &g_sw))
	{
		return 1;
	}

	if(g_sw != 0x9000)
	{
		return 2;
	}

	int data_len = 0;
	unsigned char * data = newApdu->get_response_data(&data_len);
	if(data_len < 2)
	{
		return 3;
	}

	* session_key_id = data[0] * 256 + data[1];

	return 0;
}
